/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Expressoes;

import analiseSintatica.Regras.*;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;

/**
 *
 * @author linton
 */
public class RegraIgualdade extends Regra {

    protected static Regra instancia;

    protected String estrutura = "<relacional> {<op_igualdade> <relacional>}";
    RegraRelacional regraRelacional =  RegraRelacional.getInstance();
    RegraOpIgualdade regraOpIguadade = RegraOpIgualdade.getInstance();


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraIgualdade() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraIgualdade getInstance() {
        if (instancia == null) {
            instancia = new RegraIgualdade();
        }
        return (RegraIgualdade) instancia;
    }

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        NoArvore noIgualdade = new NoArvore("<igualdade", false);

        noIgualdade.adicionaFilho(reconhecerRelacional(listaTokens));
        while (regraOpIguadade.getPrimeiro().contains(listaTokens.getFirst().getToken())){
            noIgualdade.adicionaFilho(reconhecerOp_Igualdade(listaTokens));
            noIgualdade.adicionaFilho(reconhecerRelacional(listaTokens));
        }
        return noIgualdade;
    }

    public NoArvore reconhecerRelacional(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        LinkToken token = listaTokens.getFirst();
        if (regraRelacional.getPrimeiro().contains(token.getToken())) {
            return regraRelacional.analisar(listaTokens);
        }
        ErroSintaticoException erro = new ErroSintaticoException();
        erro.addErros("Falta relacional", estrutura, token.getLinha());
        throw erro;
    }

    public NoArvore reconhecerOp_Igualdade(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        LinkToken token = listaTokens.getFirst();
        if (regraOpIguadade.getPrimeiro().contains(token.getToken())) {
            return regraOpIguadade.analisar(listaTokens);
        }
        ErroSintaticoException erro = new ErroSintaticoException();
        erro.addErros("Falta operador de igualdade", estrutura, token.getLinha());
        throw erro;

    }

    

    @Override
    protected void setPrimeiro() {
        /*P<igualdade> = P<cast>*/
        //this.primeiro = getUniao(this.primeiro, RegraRelacional.getInstance().getPrimeiro());
        primeiro.add("(");
        primeiro.add("{");
        primeiro.add("identificador");
        primeiro.add("numeroInteiro");
        primeiro.add("numeroFlutuante");
        primeiro.add("charconst");
        primeiro.add("++");
        primeiro.add("--");
        primeiro.add("&");
        primeiro.add("*");
    }

    @Override
    protected void setSeguinte() {
        /*S<igualdade> = {&&} U S<logica_e>*/
        this.seguinte.addAll(primeiro);
        this.seguinte.add("&&");
        //this.seguinte = getUniao(seguinte, RegraLogicaE.getInstance().getSeguinte());
        this.seguinte.add(";");
        this.seguinte.add(",");
        this.seguinte.add("}");
        this.seguinte.add(")");
    }
}
